﻿using System;
using System.Security.Cryptography;
using System.ServiceModel;

using Sunyi.Project.WebPoint.Common;
using Sunyi.Project.WebPoint.Configuration;
using Sunyi.Project.WebPoint.DataContract;

namespace Sunyi.Project.WebPoint.ServiceAccess
{
    public static class ServiceAccessHelper
    {
        private const string TokenLifeTimeKeyName = "TokenLifeTime";
        private const string RequestLifeTimeKeyName = "RequestLifeTime";

        #region Property

        private static int tokenLifeTime;
        public static int TokenLifeTime
        {
            get
            {
                if (tokenLifeTime <= 0)
                {
                    string tokenLifeTimeKeyName = SystemConfiguration.Authentication[TokenLifeTimeKeyName];
                    if (!string.IsNullOrEmpty(tokenLifeTimeKeyName))
                    {
                        bool flag = Int32.TryParse(tokenLifeTimeKeyName, out tokenLifeTime);

                        if (!flag) tokenLifeTime = 1;
                    }
                }

                return tokenLifeTime;
            }
        }

        private static int requestLifeTime;
        public static int RequestLifeTime
        {
            get
            {
                if (requestLifeTime <= 0)
                {
                    string requestLifeTimeKeyName = SystemConfiguration.Authentication[RequestLifeTimeKeyName];
                    if (!string.IsNullOrEmpty(requestLifeTimeKeyName))
                    {
                        bool flag = Int32.TryParse(requestLifeTimeKeyName, out requestLifeTime);

                        if (!flag) requestLifeTime = 1;
                    }
                }

                return requestLifeTime;
            }
        }

        #endregion

        public static string GenerateAccessCode(string tokenSecurityKey)
        {
            byte[] key = Convert.FromBase64String(tokenSecurityKey);

            string text = DateTime.UtcNow.Ticks.ToString();
            string value = EncrpytionHelper.TripleDesEncrypt(EnvironmentSetting.DefaultEncoding.GetBytes(text), key, key);

            return text + WebPointGlobalConstant.At + value;
        }

        internal static Token GenerateToken(Guid userId, string userName)
        {
            Token token = new Token();
            token.Id = Guid.NewGuid();
            token.UserId = userId;
            token.UserName = userName;
            token.ExpirationDate = DateTime.UtcNow.AddHours(TokenLifeTime);
            token.IssuedBy = SystemConfiguration.SystemName;
            token.IsActive = true;

            using (var provider = new TripleDESCryptoServiceProvider())
            {
                token.SecurityKey = Convert.ToBase64String(provider.Key);
            }

            return token;
        }

        internal static bool ValidateAccessCode(string tokenSecurityKey, string accessCode)
        {
            bool flag = false;

            int index = accessCode.IndexOf(WebPointGlobalConstant.At);
            if (index > 0)
            {
                string text = accessCode.Substring(0, index);
                string value = accessCode.Substring(index + 1);

                DateTime originalTime = new DateTime(long.Parse(text));
                DateTime currentTime = DateTime.UtcNow;

                // Check whether the request is expired.
                if (originalTime.AddMinutes(RequestLifeTime) > currentTime)
                {
                    byte[] key = Convert.FromBase64String(tokenSecurityKey);
                    string validValue = EncrpytionHelper.TripleDesEncrypt(EnvironmentSetting.DefaultEncoding.GetBytes(text), key, key);

                    flag = value == validValue;
                }
            }

            return flag;
        }
    }
}
